package cn.harry.modular.system.controller;

import cn.harry.common.annotation.SysLog;
import cn.harry.common.api.R;
import cn.harry.common.enums.BusinessType;
import cn.harry.component.security.utils.SecurityUtils;
import cn.harry.modular.system.domain.SysUser;
import cn.harry.modular.system.enums.ContactType;
import cn.harry.modular.system.param.EmailBindingForm;
import cn.harry.modular.system.param.PhoneBindingForm;
import cn.harry.modular.system.param.SysUserUpdateIconParam;
import cn.harry.modular.system.param.SysUserUpdatePasswordParam;
import cn.harry.modular.system.service.SysUserService;
import cn.harry.modular.system.vo.UserInfoVO;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;

/**
 * 个人中心
 *
 * @author harry
 * @公众号 Harry技术
 */
@RestController
@RequiredArgsConstructor
@Tag(name = "sys-user-profile 后台用户管理")
@RequestMapping("/sys/user/profile")
public class SysProfileController {

    private final SysUserService sysUserService;

    private static final PasswordEncoder ENCODER = new BCryptPasswordEncoder();

    @Operation(summary = "获取当前登录的个人信息")
    @GetMapping
    public R<UserInfoVO> getPersonalInfo() {
        // 获取当前用户信息
        Long userId = SecurityUtils.getUserId();
        SysUser user = sysUserService.getById(userId);
        UserInfoVO userInfoVO = new UserInfoVO();
        BeanUtil.copyProperties(user, userInfoVO);
        userInfoVO.setRoles(SecurityUtils.getRoles());
        return R.success(userInfoVO);
    }

    @Operation(summary = "修改当前登录的个人信息")
    @SysLog(title = "用户管理", businessType = BusinessType.UPDATE)
    @PutMapping
    public R<Integer> update(@RequestBody SysUser user) {
        // 更新用户信息 获取当前用户信息
        SysUser currentUser = SecurityUtils.getSysUser();

        boolean res = sysUserService.update(Wrappers.lambdaUpdate(SysUser.class)
                .set(StrUtil.isNotBlank(user.getNickName()), SysUser::getNickName, user.getNickName())
                .set(StrUtil.isNotBlank(user.getSex()), SysUser::getSex, user.getSex())
                .eq(SysUser::getId, currentUser.getId()));
        return res ? R.success() : R.failed();
    }

    @Operation(summary = "修改当前登录的个人密码")
    @PutMapping(value = "/updatePassword")
    public R<Integer> updatePassword(@RequestBody SysUserUpdatePasswordParam passwordParam) {
        Long userId = SecurityUtils.getUserId();
        SysUser dbUser = sysUserService.getById(userId);
        if (!ENCODER.matches(passwordParam.getOldPassword(), dbUser.getPassword())) {
            return R.failed("原密码不正确");
        }
        // 更新密码
        return sysUserService.updatePasswordByUserId(userId, passwordParam.getNewPassword()) ? R.success() : R.failed();
    }

    @Operation(summary = "用户头像上传")
    @SysLog(title = "用户头像上传", businessType = BusinessType.UPDATE)
    @PostMapping("/avatar")
    public R<Integer> avatar(@RequestBody SysUserUpdateIconParam param) {
        // 更新用户信息 获取当前用户信息
        SysUser currentUser = SecurityUtils.getSysUser();
        currentUser.setIcon(param.getIcon());
        // 仅允许当前登录的用户 手机号码、邮箱、性别等信息
        currentUser.setId(currentUser.getId());
        boolean res = sysUserService.update(Wrappers.lambdaUpdate(SysUser.class)
                .set(SysUser::getIcon, param.getIcon())
                .eq(SysUser::getId, currentUser.getId()));
        return res ? R.success() : R.failed();
    }


    @Operation(summary = "发送短信/邮箱验证码")
    @PostMapping(value = "/sendVerificationCode")
    public R<?> sendVerificationCode(
            @Parameter(description = "联系方式（手机号码或邮箱地址）", required = true) @RequestParam String contact,
            @Parameter(description = "联系方式类型（Mobile或Email）", required = true) @RequestParam ContactType contactType
    ) {
        boolean result = sysUserService.sendVerificationCode(contact, contactType);
        return R.success(result);
    }

    @Operation(summary = "绑定邮箱")
    @SysLog(title = "绑定邮箱", businessType = BusinessType.UPDATE)
    @PostMapping("/bindEmail")
    public R<Integer> bindEmail(@RequestBody EmailBindingForm param) {
        return sysUserService.bindEmail(param) ? R.success() : R.failed();
    }

    @Operation(summary = "绑定手机号")
    @SysLog(title = "绑定手机号", businessType = BusinessType.UPDATE)
    @PostMapping("/bindPhone")
    public R<Integer> bindPhone(@RequestBody PhoneBindingForm param) {

        return sysUserService.bindPhone(param) ? R.success() : R.failed();
    }

}
